#pragma once

#include "Interface.h"

#include "Classifier.h"
#include "Operation.h"
#include "Property.h"
#include "ProtocolStateMachine.h"
#include "Reception.h"

namespace uml {

Interface::Interface(const QString& umlType)
    : Classifier(umlType) {}

void Interface::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    Classifier::fromJson(json, errorList);
    JsonSerializable::fromJsonArray(nestedClassifiers_, "nestedClassifiers", json, errorList);
    JsonSerializable::fromJsonArray(ownedAttributes_, "ownedAttributes", json, errorList);
    JsonSerializable::fromJsonArray(ownedOperations_, "ownedOperations", json, errorList);
    JsonSerializable::fromJsonArray(ownedReceptions_, "ownedReceptions", json, errorList);
    protocol_ = JsonSerializable::create<ProtocolStateMachine>(json.value("protocol"), errorList);

    JsonSerializable::fromJsonArray(redefinedInterfaces_, "redefinedInterfaces", json, errorList);
}

void Interface::toJson(QJsonObject& json) {
    Classifier::toJson(json);
    JsonSerializable::toJsonArray(nestedClassifiers_, "nestedClassifiers", json);
    JsonSerializable::toJsonArray(ownedAttributes_, "ownedAttributes", json);
    JsonSerializable::toJsonArray(ownedOperations_, "ownedOperations", json);
    JsonSerializable::toJsonArray(ownedReceptions_, "ownedReceptions", json);
    if (protocol_) {
        QJsonObject protocol_json;
        protocol_->toJson(protocol_json);
        json.insert("protocol", protocol_json);
    }
    JsonSerializable::toJsonArray(redefinedInterfaces_, "redefinedInterfaces", json);
}

/// <summary>
/// nestedClassifiers getter
/// References all the Classifiers that are defined (nested) within the Interface.
/// </summary>
vector<shared_ptr<Classifier>>& Interface::nestedClassifiers() {
    return nestedClassifiers_;
}

/// <summary>
/// ownedAttributes getter
/// The attributes (i.e., the Properties) owned by the Interface.
/// </summary>
vector<shared_ptr<Property>>& Interface::ownedAttributes() {
    return ownedAttributes_;
}

/// <summary>
/// ownedOperations getter
/// The Operations owned by the Interface.
/// </summary>
vector<shared_ptr<Operation>>& Interface::ownedOperations() {
    return ownedOperations_;
}

/// <summary>
/// ownedReceptions getter
/// Receptions that objects providing this Interface are willing to accept.
/// </summary>
vector<shared_ptr<Reception>>& Interface::ownedReceptions() {
    return ownedReceptions_;
}

/// <summary>
/// protocol getter
/// References a ProtocolStateMachine specifying the legal sequences of the
/// invocation of the BehavioralFeatures described in the Interface.
/// </summary>
shared_ptr<ProtocolStateMachine> Interface::protocol() const {
    return protocol_;
}

/// <summary>
/// protocol setter
/// References a ProtocolStateMachine specifying the legal sequences of the
/// invocation of the BehavioralFeatures described in the Interface.
/// </summary>
void Interface::setProtocol(shared_ptr<ProtocolStateMachine> value) {
    protocol_ = value;
}

/// <summary>
/// redefinedInterfaces getter
/// References all the Interfaces redefined by this Interface.
/// </summary>
vector<shared_ptr<Interface>>& Interface::redefinedInterfaces() {
    return redefinedInterfaces_;
}

} // namespace uml
